/*
 * Flashlib - QB9 common Flash library
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package com.qb9.flashlib.screens
{
	import com.qb9.flashlib.fsm.*;
	import com.qb9.flashlib.interfaces.IDisposable;
	import com.qb9.flashlib.utils.DisplayUtil;
	
	import flash.display.*;
	
	/**
	 * Special type of FSM that manages Screen instances.
	 *
	 * <p>Each registered screen is a state in the FSM.</p>
	 *
	 * @see "examples/screenManager/ScreenManagerExample.as"
	 */
	public class ScreenManager extends FSM
	{
		protected var stage:DisplayObjectContainer;
		protected var Asset:Class;
		protected var screenInstance:DisplayObject;

		public function ScreenManager(stage:DisplayObjectContainer, Asset:Class = null)
		{
			this.stage = stage;
			this.Asset = Asset;
		}

		/**
		 * Register a screen.
		 *
		 * @param name Unique id for the screen.
		 * @param Asset Reference to a DisplayObject-derived class. The instance will be created and added to the stage when the state is entered.
		 */
		public function registerScreen(name:String, Asset:Class = null):ScreenManager
		{
			return registerState(name, new ScreenManager(stage, Asset)) as ScreenManager;
		}

		/** @inheritDoc */
		public override function enter(data:* = null):void
		{
			if (Asset != null)
			{
				screenInstance = new Asset();
				screenInstance.name = name;
				stage.addChild(screenInstance);
				screenInstance.dispatchEvent(new StateEvent(StateEvent.ENTER, data));
			}
			super.enter(data);
		}

		/** @inheritDoc */
		public override function exit(data:* = null):void
		{
			super.exit(data);
			if (screenInstance != null)
			{
				screenInstance.dispatchEvent(new StateEvent(StateEvent.EXIT, data));
				if (screenInstance is IDisposable)
					(screenInstance as IDisposable).dispose();
				else
					DisplayUtil.dispose(screenInstance);
				screenInstance = null;
			}
		}
		
		protected override function createState(stateData:Object):IState
		{
			if (stateData.asset)
				return new ScreenManager(stage, stateData.asset);
			return super.createState(stateData);
		}
	}
}
